package cn.est.service.impl;

import cn.est.config.QQLoginConfig;
import cn.est.constants.Constants;
import cn.est.constants.ErrorEnum;
import cn.est.dao.UsersMapper;
import cn.est.dto.UsersToken;
import cn.est.excepting.BizExcepting;
import cn.est.pojo.Users;
import cn.est.service.UsersService;
import cn.est.util.HttpClientUtil;
import cn.est.util.RedisUtil;
import cn.est.vo.UserVO;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.Date;
import java.util.UUID;

@Service
@Slf4j
@EnableConfigurationProperties(QQLoginConfig.class)
public class UsersServiceImpl implements UsersService {

    @Autowired
    private QQLoginConfig qqLoginConfig;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public Users getByAccount(String account) {
        Users users = usersMapper.selectByAccount(account);
        return users;
    }

    @Override
    public UsersToken loginSms(String phone, String sms) {
        //验证sms是否正确，删除验证码
        String key = Constants.LOGIN_VERIF_CODE_PREFIX + phone;
        String code = (String) redisUtil.get(key);
        log.info("验证码为:{}",code);
        if (!sms.equals(code)) {
            throw  new BizExcepting(ErrorEnum.VERIFY_CODE_ERROR.getCode(),
                    ErrorEnum.VERIFY_CODE_ERROR.getMsg());
        }
        //删除验证码
        redisUtil.del(key);
        //查询手机号对应的用户信息
        Users users = usersMapper.selectByAccount(phone);
        //如果查询没有，说明第一次使用，需要自动注册
        if (users == null) {
            users = new Users();
            users.setAccount(phone);
            users.setUserName(phone);
            users.setIsAuthentication(0);
            users.setBindStatus(0);
            users.setCreatdTime(new Date());
            users.setIsDelete(0);
            usersMapper.insert(users);
        }
        UsersToken usersToken = login(users);
        return usersToken;
    }

    @Override
    public UserVO getUserInfo(String token) {
        //在业务层根据token从redis中获取登录的用户信息
        String tokenKey = Constants.TOKEN_PREFIX + token;
        Users users = (Users) redisUtil.get(tokenKey);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(users,userVO); //利用反射 、和上面的是一样的效果
        userVO.setToken(token);

        //封装用户信息
        //返回结果
        return userVO;
    }

    @Override
    public UsersToken loginQQ(String code) throws IOException {
        //获取access_token
        String accessTokenUrl = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id="
                +qqLoginConfig.getClientId()+"&client_secret="
                +qqLoginConfig.getClientSecret()+"&code="+code+"&redirect_uri="
                +qqLoginConfig.getCallbacktUri()+"&fmt=json";
        String accessTokenJSONString = HttpClientUtil.sendGet(accessTokenUrl);
        log.info("获取access_token的响应结果是:",accessTokenJSONString);
        //响应结果转换成JSON格式
        JSONObject accessTokenJSONObject = JSON.parseObject(accessTokenJSONString);
        //得到accessToken的值
        String accessToken = accessTokenJSONObject.getString("access_token");
        //使用access_token获取openid
        String openIdUrl = "https://graph.qq.com/oauth2.0/me?access_token="+accessToken+"&fmt=json";

        String openIdJSONString = HttpClientUtil.sendGet(openIdUrl);
        log.info("获取openId的响应结果是:",openIdJSONString);
        //响应结果转换成JSON格式
        JSONObject openIdJSONObject = JSON.parseObject(openIdJSONString);
        //得到openid的值
        String openid = openIdJSONObject.getString("openid");
        //根据openid查询用户信息是否已经存在，如果没有，自动注册
        Users users = usersMapper.selectByOpenId(openid);
        if (users == null) {
            String userInfoUrl = "https://graph.qq.com/user/get_user_info?access_token="+accessToken+"&oauth_consumer_key="
                    +qqLoginConfig.getClientId()+"&openid="+openid;
            String userInfoJSONString = HttpClientUtil.sendGet(userInfoUrl);
            log.info("获取userInfo用户信息的响应结果是:",userInfoJSONString);
            //响应结果转换成JSON格式
            JSONObject userInfoJSONObject = JSON.parseObject(userInfoJSONString);
            users = new Users();
            users.setUserName(userInfoJSONObject.getString("nickname"));
            users.setSex(userInfoJSONObject.getInteger("gender_type"));
            users.setIsAuthentication(0);
            users.setFaceUrl(userInfoJSONObject.getString("figureurl_qq"));
            users.setOpenId(openid);
            users.setCreatdTime(new Date());
            users.setIsDelete(0);
            usersMapper.insert(users);

        }
        //自动登录
        UsersToken usersToken = login(users);
        //返回结果
        return usersToken;
    }

    private UsersToken login(Users users) {
        //生成独一无二的token
        String token = UUID.randomUUID().toString().replace("-", "");
        redisUtil.setHours(Constants.TOKEN_PREFIX+token,users,2);
        UsersToken usersToken = new UsersToken();
        usersToken.setToken(token);
        return usersToken;
    }
}
